<?php

	/**
	* Starts session
	*/
	session_start();
	
	/**
	* Configuration variables
	*/
	class CmsConfig{
		
		/**
		* e-mail address(es) to recieve comment notifications
		*/
		public static $comment_alert_to = "webmaster@";
		
		/**
		* Allowed tags for Content-comment fields
		*/
		public static $comment_allowable_tags = "<br><b><strong><i><em><sup><sub><table><font><span>";
		
		/**
		* URL of stylesheet for comments iframe
		*/
		public static $comments_css = '';
		
		/**
		* Amount of stars that will be used for rating content
		*/
		public static $content_stars = 5;
		
		/**
		* Link to content. [ID] is used to replace with the content id, and [TITLE] is replaced with the url-friendly title.
		*/
		public static $content_link = "/content.php?id=[ID]&t=[TITLE]";
		
		/**
		* Link to category. [ID] is used to replace with the category id, and [NAME] is replaced with the url-friendly name.
		*/
		public static $category_link = "/content.php?c=[ID]&t=[NAME]";
		
	}
	
	define('OK', 'OK');
	define('CREATE', 1);
	define('MODIFY', 2);
	define('ATTACH', 3);
	define('DETACH', 4);
	define('COMMENT', 5);
	define('OPEN', 6);
	define('ALLOWCOMMENTS', 2);
	define('ALLOWRATING', 4);
	define('SEXYBAR', 8);
		
	$data_path_possibilities = array("./", "../", "../../", "../../../");
	$data_path = "";
	
	foreach($data_path_possibilities as $dir){
		
		$data_path = $dir . "cms-data/";
		
		if( file_exists($data_path . "cms-config.php") ) break;
		
	}
	
	define('CMS_DATA', $data_path);
		
	//Include the config file
	@include(CMS_DATA . 'cms-config.php');
	
	//Check if import was successfull
	if(!class_exists('ConnectionParameters')){	
		die("No config reached by Moka CMS");
	}
	
	//Includes
	include 'datalatte.php';
	include 'records.php';
	include 'strings.php';
	
	function cmsTryConfig($var, $value){
		if( isset($GLOBALS[$val]) ){
			return $GLOBALS[$val];
		}else{
			return $value;
		}
	}
	
		   
	class Session{
		
		/**
		* Adds an error message or dumps the errors as paragraphs.
		*/
		public static function error($message = ""){
			
			if(empty($message)){
				if(isset($_SESSION['err'])){
					foreach($_SESSION['err'] as $msg){
						echo "<p class=err>" . $msg . "</p>";
					}
					unset($_SESSION['err']);
				}
			}else{
				if(!isset($_SESSION['err'])){
					$_SESSION['err'] = array();
				}
				$_SESSION['err'][] = $message;
			}
			
		}
		
		/**
		* Returns a boolean indicating if some user is currently logged
		*/
		public static function logged(){
			return isset($_SESSION['userid']);
		}
		
		/**
		* Returns the id of the currently logged user
		*/
		public static function user(){
			if(self::logged()){
				return $_SESSION['userid'];
			}else{
				return NULL;
			}
		}
		
		/**
		* Returns the level of the currently logged user
		*/
		public static function level(){
			if(self::logged()){
				return $_SESSION['userlevel'];
			}else{
				return NULL;
			}
		}
		
		/**
		* Returns if the currently logged user is a site administrator
		*/
		public static function admin(){
			if(self::logged()){
				return $_SESSION['useradmin'];
			}else{
				return NULL;
			}
		}
		
		/**
		* Ensures that a session is currently open. Otherwise, header will redirect to 
		* index.php
		*/
		public static function must(){
			if(!self::logged()){
				header('Location: index.php');
				die();
			}
		}
		
	}//End Class Session
	
	/**
	* Class that handles the general aspects of the Content Management System
	*/
	class Cms{
		
		/**
		* Prevents the browser from caching the page
		*/
		function nocache(){
			header("Cache-Control: no-cache, must-revalidate"); 
			header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
		}

		/**
		* Returns if client is an iPhone
		* @return boolean
		*/
		function is_iphone(){
			return strpos($_SERVER['HTTP_USER_AGENT'],"iPhone");
		}
		
		/**
		* Returns if client is a BlackBerry
		*/
		function is_blackberry(){
			 strpos($_SERVER['HTTP_USER_AGENT'],"BlackBerry");
		}
		
		/**
		* Returns the passed string as a url-friendly string
		*/
		function url_friendly($str){
			return str_replace(' ', '-', $str);
		}
		
		/**
		* Parses a mysql-like date and returns a unix timestamp
		*/
		public static function parse_date($datetime){
		   $val = explode(" ",$datetime);
		   $date = explode("-",$val[0]);
		   $time = explode(":",$val[1]);
		   return mktime($time[0],$time[1],$time[2],$date[1],$date[2],$date[0]);
		}
		
	}//End class Cms
	
	class Attachment extends cmsAttachmentBase{
		
		/**
		* Returns an array of Attachment objects that belong to the specified content id.
		* @param integer contentid Id of content to get attachments
		* @return array
		*/
		static function bycontentid($contentid){
			return DataLatte::arrayof('Attachment', "SELECT * FROM cmsAttachment WHERE cmsContent_idcontent = '$contentid'");
		}
		
		/**
		 * Convert bytes to human readable format
		 *
		 * @param integer bytes Size in bytes to convert
		 * @return string
		 */
		static function bytesToSize($bytes, $precision = 2)
		{  
			$kilobyte = 1024;
			$megabyte = $kilobyte * 1024;
			$gigabyte = $megabyte * 1024;
			$terabyte = $gigabyte * 1024;
		   
			if (($bytes >= 0) && ($bytes < $kilobyte)) {
				return $bytes . ' B';
		 
			} elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
				return round($bytes / $kilobyte, $precision) . ' KB';
		 
			} elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
				return round($bytes / $megabyte, $precision) . ' MB';
		 
			} elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
				return round($bytes / $gigabyte, $precision) . ' GB';
		 
			} elseif ($bytes >= $terabyte) {
				return round($bytes / $gigabyte, $precision) . ' TB';
			} else {
				return $bytes . ' B';
			}
		}
		
		/**
		* Returns the file extension of the file (without the dot)
		*/
		static function file_extension($filename){
			return substr($filename, strrpos($filename, '.') + 1);
		}
		
		/**
		* Gets the CSS class name for the specified file name icon. 
		* @param string filename Name of the file to analyze extension
		* @return string
		*/
		static function fileCss($filename){
			$ext = Attachment::file_extension($filename);
			
			switch($ext){
				case 'pdf':
					return 'icon-pdf';
				case 'doc':
				case 'docx':
					return 'icon-word';
				case 'xls':
				case 'csv':
				case 'xlsx':
					return 'icon-excel';
				case 'ppt':
				case 'pptx':
					return 'icon-powerpoint';
				case 'zip':
				case 'rar':
					return 'icon-zip';
				case 'jpg':
				case 'jpeg':
				case 'png':
				case 'gif':
				case 'bmp':
				case 'ico':
					return 'icon-image';
				default:
					return 'icon-file';
			}
		}
		
	}
	
	/**
	* Represents a content record on the database.
	*/
	class Content extends cmsContentBase{	
	
		/**
		* Writes in the output the necessary header-section tags: stylesheets and scripts, jQuery 1.4.2 and jQuery-UI 1.8.1
		*/
		public static function headertags(){
			echo '<link rel="stylesheet" type="text/css" href="/cms/css/custom-theme/jquery-ui-1.8.1.custom.css"/>' .
				'<link rel="stylesheet" type="text/css" href="/cms/css/cms.css"/>' . 
				'<script type="text/javascript" src="/cms/strings.php?js"></script>' .
				'<script type="text/javascript" src="/cms/js/jquery-1.4.2.min.js"></script>' .
				'<script type="text/javascript" src="/cms/js/jquery-ui-1.8.1.custom.min.js"></script>'.
				'<script type="text/javascript" src="/cms/js/rater.js"></script>' . 
				'<script type="text/javascript" src="/cms/js/autoheight.js"></script>';
		}
		
		/**
		* Creates a content from specified id
		* @param integer idcontent Id of the content to get
		*/
		public static function byid($idcontent){
			return DataLatte::oneof('Content', "SELECT * FROM cmsContent WHERE idcontent = '$idcontent'");
		}
		
		/**
		* Gets the newest content. Useful for blogs.
		*/
		public static function newest(){
			return DataLatte::oneof('Content', "SELECT * FROM cmsContent WHERE online = 1 ORDER BY created DESC LIMIT 1");
		}
		
		/**
		* Gets the newest content. Useful for blogs.
		*/
		public static function latest($size = 5){
			return DataLatte::arrayof('Content', "SELECT * FROM cmsContent WHERE online = 1 ORDER BY created DESC LIMIT $size");
		}
		
		/**
		* Writes the full body of the content: title, intro, text, attachmens, rater, sexybar and comments with comment placer.
		*
		*/
		public function fullbody(){
			
			global $strings;
			
			echo '<div class="content-body">';
			
			if($this->online){
			
				echo $this->title();
				echo $this->intro();
				echo $this->text();
				echo $this->attachments();
				
				if( ($this->options & ALLOWRATING ) == ALLOWRATING )
					echo $this->rater();
				
				if( ($this->options & SEXYBAR ) == SEXYBAR )
					echo $this->sexybar();
				
				if( ($this->options & ALLOWCOMMENTS ) == ALLOWCOMMENTS )
					echo $this->comments();
					
			}else{
				echo '<p>' . $strings['contentoffline'] . '</p>';
			}
			
			echo '</div>';
			
			//Insert visits on content
			DataLatte::update("INSERT INTO cmsVisit(cmsContent_idcontent, ip, time) VALUES('" . $this->idcontent . "', '" . $_SERVER['REMOTE_ADDR'] . "', NOW())");
		}
		
		public function title(){
			return '<h1 class="content-title">' . $this->title . "</h1>";
		}
		
		public function intro(){
			return '<h2 class="content-intro">' . $this->intro . "</h2>";
		}
		
		public function text(){
			return '<div class="content-text">' . $this->text . "</div>";
		}
		
		public function rater(){
			
			global $strings;
			$stars = '';
			
			for($i = 1; $i <= CmsConfig::$content_stars; $i++){
				$stars .= '<div class="content-rater-star ' . ( $i <= $this->rating ? 'content-rater-star-on' : 'content-rater-star-off') . '"><span>' . $i . '</span></div>';
			}
			
			return 
				'<div class="content-rater"><div class="content-rater-id invisible">' . $this->idcontent .'</div>' .
					'<div class="content-rater-stars">' .
						$stars .
					'</div>' .
					'<div class="content-rater-title">' . $strings['rate'] . '</div>' .
				'</div>'
			;
		}
		
		public function sexybar(){
			$title = urlencode($this->title);
			$url = $this->getlink(true);
			?>
			<div class='sexy-bookmarks'>
                <ul class='socials'>
                    <li class='sexy-delicious'><a href="http://del.icio.us/post?url=<?=$url?>&title=<?=$title?>" target='_blank'></a></li>
                    <li class='sexy-digg'><a href='http://digg.com/submit?url=<?=$url?>&title=<?=$title?>' target='_blank'></a></li>
                    <li class='sexy-technorati'><a href='http://technorati.com/faves?add=<?=$url?>&title=<?=$title?>' target='_blank'></a></li>
                    <li class='sexy-reddit'><a href='http://www.reddit.com/submit?url=<?=$url?>&title=<?=$title?>' target='_blank'></a></li>
                    <li class='sexy-stumble'><a href='http://www.stumbleupon.com/submit?url=<?=$url?>&title=<?=$title?>' target='_blank'></a></li>
                    <li class='sexy-designfloat'><a href='http://www.designfloat.com/submit.php?url?<?=$url?>&title=<?=$title?>' target='_blank'></a></li>
                    <li class='sexy-facebook'><a href='http://www.facebook.com/sharer.php?u=<?=$url?>&title=<?=$title?>' target='_blank'></a></li>
                    <li class='sexy-twitter'><a href='http://twitter.com/home?status=<?=($title . ": " . $url)?>' target='_blank'></a></li>
                    <li class='sexy-furl'><a href='http://www.furl.net/storeIt.jsp?u=<?=$url?>&title=<?=$title?>' target='_blank'></a></li>
                    <li class='sexy-syndicate'><a href='/feed.rss' title='Subscribe to RSS'></a></li>
                </ul>
              </div>
			<?
		}
		
		public function attachments(){
			$atts = Attachment::bycontentid($this->idcontent);
			$lis = "";
			
			foreach($atts as $a)
				$lis .= "<li class='content-attachment'>" . 
						"<div class='content-attachment-icon icon " . Attachment::fileCss($a->name) . "'></div>" .
						"<span class='content-attachment-name'>" . $a->name . "</span>" .
						"<span class='content-attachment-size'>(" . Attachment::bytesToSize($a->bytes) . ")</span>" .
						"</li>";
			
			return "<ul class='content-attachments'>$lis</ul>";
		}
		
		public function comments(){
			return "<iframe class='content-comments autoHeight' src='/cms/comments.php?idcontent=" . $this->idcontent . "' frameborder='0'></iframe>";
		}
		
		public function getlink($full = FALSE){
			return ($full ? 'http://' . $_SERVER['HTTP_HOST'] : '') . str_replace('[TITLE]', Cms::url_friendly($this->title), str_replace("[ID]", $this->idcontent, CmsConfig::$content_link));
		}
		
		/**
		* Gets an array of the categories tree for the content
		*/
		public function get_category_chain(){
			return Category::get_chain($this->cmsCategory_idcategory);
		}
		
			
	}//End class Content
	
	class Category extends cmsCategoryBase{
		
		/**
		* Gets an array of the categories starting from the specified one
		*/
		public static function byid($idcategory){
			return DataLatte::oneof('Category', "SELECT * FROM cmsCategory WHERE idcategory = '" . $idcategory . "'");
		}
		 
		/**
		* Gets an array of the categories starting from the specified one
		*/
		public static function get_chain($idcategory){
			
			$arr = array();
			$categories = DataLatte::arrayof('Category', "SELECT * FROM cmsCategory");
			$curcat = $idcategory;
			
			while($curcat){
				foreach($categories as $category){
					if($category->idcategory == $curcat){
						$arr[] = $category;
						$curcat = $category->cmsCategory_idcategory;
					}
				}
			}
			
			array_reverse($arr);
			
			return $arr;
		}
		
		/**
		* Gets an array of categories that are sub-categories for $this
		*/
		public function get_categories(){
			return DataLatte::arrayof('Category', "SELECT * FROM cmsCategory WHERE cmsCategory_idcategory = '" . $this->idcategory . "'");
		}
		
		/**
		* Gets the contents
		*/
		public function get_contents(){
			return DataLatte::arrayof('Content', "SELECT * FROM cmsContent WHERE cmsCategory_idcategory = '" . $this->idcategory . "'");
		}
		
		/**
		* Gets an array of categories contining it's sub-categories recursively
		*/
		public static function get_tree($idcategory){
		}
		
		/**
		* Writes the body of category
		*/
		public function fullbody(){
			echo '<div class="category-body">';
			echo '<h1 class="category-name">' . $this->name . '</h1>';
			echo '<ul class="category-list">';
			foreach($this->get_categories() as $subcat)
				echo '<li><a href="' . $subcat->getlink() . '">' . $subcat->name . '</a></li>';
			echo '</ul>';
			echo '<ul class="content-list">';
			foreach($this->get_contents() as $ct)
				echo '<li><a href="' . $ct->getlink() . '">' . $ct->title . '</a><div>' . $ct->intro . '</div></li>';
			echo '</ul>';
			echo '</div>';
		}
		/**
		* Gets the link to the category, configurable by Cms::category_link
		*/
		public function getlink($full = FALSE){
			return ($full ? 'http://' . $_SERVER['HTTP_HOST'] : '') . str_replace('[NAME]', Cms::url_friendly($this->title), str_replace("[ID]", $this->idcategory, CmsConfig::$category_link));
		}
		
	}//End class Category
	
	class User extends cmsUserBase{
	}//End class User
	
	/**
	* Represents a comment made to content or attachments
	*/
	class Comment extends cmsCommentBase{
		
		/**
		* Gets the commments made to a content entry
		* @param integer contentid Id of content entry
		* @param integer page Page of comments
		* @param integer pagesize Number of comments per page
		* @return array
		*/
		public static function bycontentid($contentid, $page = 1, $pagesize = 10){
			return DataLatte::arrayof('Comment', "SELECT * FROM cmsComment WHERE cmsContent_idcontent = '$contentid' AND deleted = '0' ORDER BY created DESC LIMIT " . (($page - 1) * $pagesize) . ", $pagesize ");
		}
		
		/**
		* Gets the amount of comments made to a content entry
		* @param integer contentid Id of content entry
		*/
		public static function bycontentid_count($contentid){
			return DataLatte::getsingle("SELECT COUNT(*) FROM cmsComment WHERE cmsContent_idcontent = '$contentid' AND deleted = '0' ORDER BY created DESC ");
		}
		
	}//End class Comment
	
	class Log extends cmsLogBase{
		/**
		* Adds a log registry
		* @param integer action Action identifier of the log entry
		* @param integer idcontent Id of content entry related to the entry
		* @param string data Additional data to append to the log entry
		*/
		public static function add($action, $idcontent, $data = ""){
			$log = new Log();
			$log->cmsUser_iduser = Session::user();
			$log->cmsContent_idcontent = $idcontent;
			$log->date = DataLatte::getsingle("SELECT NOW()");
			$log->action = $action;
			$log->text = $data;
			$log->insert();
		}
	}//End Class Log
	
	if(isset($_GET['dumprecords'])){
		DataLatte::dumprecords();
	}

?>